<?php
/**
 * Created by PhpStorm.
 * User: mofeng
 * Date: 16/9/5
 * Time: 上午10:37
 */

namespace App\Api\Account\Controllers;


use App\Api\Account\Models\Chat;
use App\Api\Account\Models\ChatMessage;
use App\Api\Account\Models\CommitTag;
use App\Api\Account\Models\ContactUs;
use App\Api\Account\Models\PaymentAccount;
use App\Api\Account\Models\RechargeOrder;
use App\Api\Account\Models\SystemMessageUser;
use App\Api\Account\Models\UserAccount;
use App\Api\Account\Models\UserAccountTransaction;
use App\Api\Account\Models\UserCommit;
use App\Api\Account\Models\Withdraw;
use App\Api\Account\Requests\AccountRechargeRequest;
use App\Api\Account\Requests\AccountWithdrawRequest;
use App\Api\Account\Services\BusinessService;
use App\Api\Auth\Models\UsersOpenId;
use App\Api\Web\Models\House;
use App\Http\Controllers\Controller;
use App\KvSet;
use App\Libs\Payment\RockyPayLibrary;
use App\Libs\Wechat\WechatService;
use App\User;
use Carbon\Carbon;
use DB;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class AccountController extends Controller
{
    public function balance(Request $request, $user_id = null)
    {
        $user = authUser();
        $user_id = $user->id;
        $account = UserAccount::where('user_id', $user_id)->first();
        if (empty($account)) {
            return $this->formatOutput(['balance' => 0, 'integral' => 0, 'freeze' => 0]);
        }


        return $this->formatOutput($account);
    }

    public function transaction(Request $request)
    {
        $params = $request->all();
        unset($params['api_token']);
        $user = authUser();
        if (!$user->hasRole('admin')) {
            $params['user_id'] = $user->id;
            // 查询类型:
            // recharge 充值记录
            // transaction 交易流水
            if (isset($params['trans_type'])) {
                $searchType = $params['trans_type'];
                unset($params['trans_type']);
                switch ($searchType) {
                    //加款
                    case 'recharge':
                        $params['source_type__in'] = 'moderator,compensation,rebate';
                        break;
                    //订单流水
                    case 'transaction':
                        $params['source_type'] = 'allotment_order';
                        break;
                }
            }
            // 开始时间
            if (isset($params['start']) && ($time = strtotime($params['start'])) !== false) {
                unset($params['start']);
                $start = date('Y-m-d 00:00:00', $time);
                $params['created_at__gte'] = $start;
            }

            // 结束时间
            if (isset($params['end']) && ($time = strtotime($params['end'])) !== false) {
                unset($params['end']);
                $end = date('Y-m-d 23:59:59', $time);
                $params['created_at__lte'] = $end;
            }
        }

        $result = $this->search(new UserAccountTransaction(), $params);
        return $this->formatOutput($result);
    }

    public function transactionMine(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $type = data_get($params, 'type', []);
        $page = data_get($params, 'page', '');
        $pageSize = data_get($params, 'page_size', '');
        $m = UserAccountTransaction::where('user_id', '=', $user->id);

        if (!empty($type)) {
            $m = $m->where('type', $type);
        }
        $m = $m->orderBy('id', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page)
            ->toArray();

        return $this->formatOutput($m);

    }

    public function recharge(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $productId = data_get($params, 'product_id', '');
        if (empty($productId)) {
            throw new \LogicException('请重新选择面值', 100);
        }


        $total = $productId;
        $order = RechargeOrder::create([
            'name' => '充值'.$total.'元',
            'user_id' => $user->id,
            'product_id' => $productId,
            'total' => $total,
            'status' => '100'
        ]);

        $usersOpenId = UsersOpenId::query()
            ->where('app_id', '=', config("payment.jueqiweilaixcx.wechat.app_id", ''))
            ->where('user_id', '=', $user->id)
            ->first();
        $openId = data_get($usersOpenId, 'open_id');
        $options = [
            'order_id' => 'rentrecharge'.Carbon::now()->format('Ymd').data_get($order, 'id'),
            'notify_url' => env('APP_URL'). '/api/web/account/'.data_get($order, 'id').'/mini-payment/notify',
            'body' => '充值'.$productId.'元',
            'description' => '充值'.$productId.'元',
            'openid' => $openId,
            'total' => $total
        ];
        $rockyPay = new RockyPayLibrary('jueqiweilaixcx', 'wechat');
        $order->payment = $rockyPay->payment('wx_miniapp', $options);
//        $order->payment = $rockyPay->payment('wx_miniapp', $options);

        return $this->formatOutput($order);
    }

    public function rechargeNotify(Request $request, $orderId)
    {
        $params         = $request->all();
        $order          = RechargeOrder::find($orderId);
        $driver         = 'wechat';
        $rockyPay   = new RockyPayLibrary('jueqiweilaixcx', $driver);
        $notifyInfo = $rockyPay->wxMpNotify('wx_miniapp', $params);

        // 支付通知数据获取成功
        if ($notifyInfo['result_code'] == 'SUCCESS' && $notifyInfo['return_code'] == 'SUCCESS' && data_get($order, 'status', 0) == 100) {
            $order->update([
                'status' => '200',
                'payment_txn' => $notifyInfo['transaction_id'],
            ]);
            BusinessService::commonTransaction(data_get($order, 'user_id', ''), $notifyInfo['total_fee']/100, $orderId, 'recharge_order', '充值'.data_get($order, 'product_id', '').'元');

//            $order->attachPaymentTrade($notifyInfo['total_fee'], $method, $paymentAccount, $notifyInfo['transaction_id'], '');
//            $order->save();
        }

        return 'SUCCESS';
    }

    public function vipProducts(Request $request)
    {
        $config = config('vip.products');

        return $this->formatOutput($config);
    }

    public function vipOrder(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $productId = data_get($params, 'product_id', '');

        if (empty($productId)) {
            throw new \LogicException('请重新选择会员', 100);
        }

        $config = config('vip.products', []);
        $r = collect($config)->where('id', (string)$productId)->first();

        BusinessService::commonTransaction($user->id, -data_get($r, 'total', 0), 0, 'vip_order', '购买'.data_get($r, 'title', ''));

        $userVip = BusinessService::attacheVip($user, data_get($r, 'days', 0), data_get($r, 'integral', 0));

        $endAt = data_get($userVip, 'end', '');
        $userVip->update([
            'product_id' => $productId,
            'product_name' => data_get($r, 'title', ''),
        ]);

        $house = House::where('user_id', '=', $user->id)
            ->where('status', '>', -900)
            ->orderBy('id', 'desc')
            ->first();

        if (!empty($house)) {
            $house->update([
                'ding_start_at' => Carbon::now()->toDateTimeString(),
                'ding_end_at' => $endAt,
            ]);
        }


        return $this->formatOutput('success');
    }

    public function signIn(Request $request)
    {
        $params = $request->all();
        $user = authUser();

        $key = 'SIGN_IN_COUNT_'.$user->id;
        $kvSet = KvSet::where('key', '=', $key)
            ->first();
        $cache = data_get($kvSet, 'value', 0);

        $integral = bcadd($cache, 10);
        BusinessService::commonIntegralTransaction(data_get($user, 'id'), $integral, 0, 'sign_in', '签到送积分');

        kvSet($key, $integral);
        kvSet('SIGN_IN_DATE_'.$user->id, Carbon::now()->format('Y-m-d'));

        return $this->formatOutput([
            'integral' => $integral,
        ]);
    }

    public function getSignInStatus(Request $request)
    {
        $params = $request->all();
        $user = authUser();


        $key = 'SIGN_IN_DATE_'.$user->id;
        $kvSet = KvSet::where('key', '=', $key)
            ->first();
        $cache = data_get($kvSet, 'value', 0);

        $now = Carbon::now()->format('Y-m-d');
        $isSignIn = 0;
        if ($now <= $cache) {
            $isSignIn = 1;
        }


        return $this->formatOutput([
            'is_sign_in' => $isSignIn,
        ]);
    }


    public function commit(Request $request)
    {
        $user = authUser();
        $params = $request->all();
        $commit = data_get($params, 'commit_tag_id', []);
        $hostUserId = data_get($params, 'host_user_id', '');

        if (empty($hostUserId) || empty($commit)) {
            throw new \LogicException('缺少必要参数', 100);
        }
        if ($user->id == $hostUserId) {
            throw new \LogicException('不可以给自己评论哦', 300);
        }


        if (is_array($commit) && !empty($commit)) {
            foreach ($commit as $v) {
                $commitM = CommitTag::find($v);
                try {
                    $appId = config('payment.jueqiweilaixcx.wechat.app_id');
                    $secret = '';
                    if ($appId == config('payment.jueqiweilaixcx.wechat.app_id')) {
                        $secret = config('payment.jueqiweilaixcx.wechat.app_secret');
                    }
                    $wechat  = new WechatService($appId, $secret);
                    $r = $wechat->msgSecCheck(data_get($commitM ,'tag'));
                } catch (\LogicException $e) {
                    continue;
                }
                $isExist = UserCommit::where('user_id', '=', $user->id)
                    ->where('host_user_id', '=', $hostUserId)
                    ->where('commit_tag_id', '=', $v)
                    ->first();
                if (empty($isExist)) {
                    UserCommit::create([
                        'user_id' => $user->id,
                        'host_user_id' => $hostUserId,
                        'commit_tag_id' => $v,
                        'commit_tag_name' => data_get($commitM, 'tag', ''),
                    ]);
                }
            }
        } else {
            throw new \LogicException('系统错误，请稍后重试', 200);
        }
        SystemMessageUser::create([
            'user_id' => $hostUserId,
            'type' => 2,
            'message' => '你收到'.data_get($user, 'name', '').'的评价',
        ]);
        toWxMessage($user, $hostUserId, '你收到'.data_get($user, 'name', '').'的评价', '通知', 'comment');

        return $this->formatOutput('success');
    }

    public function getCommitMine(Request $request)
    {
        $params = $request->all();
        $pageSize = data_get($params, 'page_size', 20);
        $page = data_get($params, 'page', 1);

        $user = authUser();
        $r = UserCommit::where('user_commit.user_id', '=', $user->id)
//            ->join('commit_tag as ct', 'ct.id', '=', 'user_commit.commit_tag_id')
            ->select('commit_tag_name as tag')
            ->orderBy('user_commit.id', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page)
            ->toArray();

        return $this->formatOutput($r);
    }

    public function getCommitHost(Request $request)
    {

        $params = $request->all();
        $pageSize = data_get($params, 'page_size', 20);
        $page = data_get($params, 'page', 1);
        $hostUserId = data_get($params, 'host_user_id', '');
        if (empty($hostUserId)) {
            throw new \LogicException('缺少必要参数', 100);
        }
        $r = UserCommit::where('host_user_id', '=', $hostUserId)
//            ->join('commit_tag as ct', 'ct.id', '=', 'user_commit.commit_tag_id')
            ->select('commit_tag_name as tag')
            ->orderBy('user_commit.id', 'desc')
            ->get();
        $return = [];
        foreach ($r as $v) {
            $tag = data_get($v, 'tag', '');
            if (!isset($return[$tag])) {
                $return[$tag] = 1;
            } else {
                $return[$tag]++;
            }
        }
        $rs = [];
        foreach ($return as $k => $v) {
            $rs[] = ['title' => $k, 'num' => $v];
        }
//            ->paginate($pageSize, ['*'], 'page', $page)
//            ->toArray();

        return $this->formatOutput($rs);
    }

    public function getCommitTag(Request $request)
    {
        $r = CommitTag::get();
        return $this->formatOutput($r);
    }






    public function withdraw(Request $request)
    {
        $params = $request->all();
        $amount = data_get($params, 'amount', 0);
        $to = data_get($params, 'to', 0);
        if (!$to) {
            throw new \LogicException('请选择提现方式', 100);
        }
        $user = authUser();
        if ($amount <= 0) {
            throw new \LogicException('请确认要提现的金额', 100);
        }

        $r = Withdraw::create([
            'user_id' => $user->id,
            'to' => $to,
            'amount' => $amount,
            'status' => '-900',
        ]);

        BusinessService::commonTransaction($user->id, -$amount, data_get($r, 'id'), 'withdraw', '提现');

        Withdraw::find(data_get($r, 'id'))
            ->update([
                'status' => 100,
            ]);

        return $this->formatOutput($r);
    }

    public function withdrawAdminIndex(Request $request)
    {
        $params = $request->all();
        $pageSize = data_get($params, 'page_size', 20);
        $page = data_get($params, 'page', 1);

        $r = Withdraw::leftJoin('users as u', 'u.id', '=', 'withdraw.user_id')
            ->where('withdraw.status', '>', -900)
            ->select('withdraw.*', 'u.head_img', 'u.name', 'u.bank', 'u.bank_person', 'u.bank_account', 'u.alipay')
            ->paginate($pageSize, ['*'], 'page', $page)
            ->toArray();

        foreach ($r['data'] as $k => $v) {
            $r['data'][$k]['status_name'] = data_get(Withdraw::$status, data_get($v, 'status'), '未知');
            $r['data'][$k]['to_name'] = data_get(Withdraw::$to, data_get($v, 'to'), '未知');
        }

        return $this->formatOutput($r);
    }

    public function withdrawAdminUpdate(Request $request)
    {
        $params = $request->all();
        $id = data_get($params, 'id', '');
        if (empty($id)) {
            throw new \LogicException('缺少必要参数', 100);
        }

        $status = data_get($params, 'status', '');
        $memo = data_get($params, 'memo', '');

        $updates = [];
        empty($status) ? : $updates['status'] = $status ;
        empty($memo) ? : $updates['memo'] = $memo ;

        if (!empty($updates)) {
            Withdraw::find($id)
                ->update($updates);
        }

        return $this->formatOutput(
            'success'
        );

    }

    public function chat(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $toUserId = data_get($params, 'to_user_id', '');
        $type = data_get($params, 'type', 1);
        $message = data_get($params, 'message', '');

        $appId = config('payment.jueqiweilaixcx.wechat.app_id');
        $secret = '';
        if ($appId == config('payment.jueqiweilaixcx.wechat.app_id')) {
            $secret = config('payment.jueqiweilaixcx.wechat.app_secret');
        }
        $wechat  = new WechatService($appId, $secret);
        $r = $wechat->msgSecCheck($message);

        $chat = Chat::where('user_id', '=', $user->id)
            ->where('to_user_id', '=', $toUserId)
            ->first();
        if (empty($chat)) {
            $chat = Chat::where('user_id', '=', $toUserId)
                ->where('to_user_id', '=', $user->id)
                ->first();

            if (empty($chat)) {
                $chat = Chat::create([
                    'user_id' => $user->id,
                    'to_user_id' => $toUserId,
                ]);
            }
        }

        if (!empty($message)) {
            ChatMessage::create([
                'type' => $type,
                'chat_id' => data_get($chat, 'id', ''),
                'user_id' => $user->id,
                'message' => $message,
            ]);
            $chat->update([
                'last_msg' => $message
            ]);
            if (data_get($chat, 'user_id', '') == $user->id) {
                $r = \DB::table('chat')->where('id', data_get($chat, 'id', ''))->increment('un_read_count2');
            } else {
                $r = \DB::table('chat')->where('id', data_get($chat, 'id', ''))->increment('un_read_count1');
            }
            toWxMessage($user, $toUserId, $message, '聊天', 'chat');
        }

        return $this->formatOutput('success');
    }

    public function chatIndex(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $pageSize = data_get($params, 'page_size', 20);
        $page = data_get($params, 'page', 1);

        $chats = Chat::where(function ($query) use ($user) {
            $query->where('user_id', '=', $user->id)
                ->orwhere('to_user_id', '=', $user->id);
        })
            ->leftJoin('users as u1', 'u1.id', '=', 'chat.user_id')
            ->leftJoin('users as u2', 'u2.id', '=', 'chat.to_user_id')
            ->select('chat.*', 'u1.name as u1name', 'u2.name as u2name', 'u1.id as u1id', 'u2.id as u2id', 'u1.head_img as u1head_img', 'u2.head_img as u2head_img')
            ->orderBy('chat.updated_at', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page)
            ->toArray();


        foreach ($chats['data'] as $k => $chat) {
            if (data_get($chat, 'u1name', '') == $user->name) {
                $chats['data'][$k]['to_username'] = data_get($chat, 'u2name', '');
                $chats['data'][$k]['to_user_head_img'] = data_get($chat, 'u2head_img', '');
                $chats['data'][$k]['to_userid'] = data_get($chat, 'u2id', '');
                $chats['data'][$k]['to_user_unread_count'] = data_get($chat, 'un_read_count1', '');
            } else {
                $chats['data'][$k]['to_username'] = data_get($chat, 'u1name', '');
                $chats['data'][$k]['to_user_head_img'] = data_get($chat, 'u1head_img', '');
                $chats['data'][$k]['to_userid'] = data_get($chat, 'u1id', '');
                $chats['data'][$k]['to_user_unread_count'] = data_get($chat, 'un_read_count2', '');
            }
        }

        return $this->formatOutput($chats);
    }

    public function messageIndex(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $toUserId = data_get($params, 'to_user_id', '');
//        $chatId = data_get($params, 'chat_id', '');
        $pageSize = data_get($params, 'page_size', 20);
        $page = data_get($params, 'page', 1);
        if ($toUserId == 'system') {
            $r = SystemMessageUser::where('user_id', '=', $user->id)
                ->leftJoin('system_message as sm', 'sm.id', '=', 'system_message_user.system_msg_id')
                ->select('system_message_user.*', 'sm.message as smmessage', 'system_message_user.message as smumessage')
                ->orderBy('id', 'desc')
                ->paginate($pageSize, ['*'], 'page', $page)
                ->toArray();

            foreach ($r['data'] as $k => $v) {
                $type = data_get($v, 'type', '');
                if ($type == 1) {
                    $r['data'][$k]['message'] = data_get($v, 'smmessage', '');
                } elseif ($type == 2) {
                    $r['data'][$k]['message'] = data_get($v, 'smumessage', '');
                }
            }

            return $this->formatOutput($r);



        }
        $chat = Chat::where('user_id', '=', $user->id)
            ->where('to_user_id', '=', $toUserId)
            ->first();
        $cuser = User::find(data_get($chat, 'user_id'));
        $toUser = User::find(data_get($chat, 'to_user_id'));
        if (empty($chat)) {
            $chat = Chat::where('user_id', '=', $toUserId)
                ->where('to_user_id', '=', $user->id)
                ->first();
            $toUser = User::find(data_get($chat, 'user_id'));
            $cuser = User::find(data_get($chat, 'to_user_id'));
        }

        if (empty($chat)) {
            return $this->formatOutput(['data' => []]);
        }
        $chatId = data_get($chat, 'id');


        if (data_get($chat, 'user_id', '') == $user->id) {
            $chat->update([
                'un_read_count1' => 0
            ]);
        } else {
            $chat->update([
                'un_read_count2' => 0
            ]);
        }
        $messages = ChatMessage::where('chat_id', '=', $chatId)
            ->orderBy('id', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page)
            ->toArray();

        if (!empty($messages['data'])) {
            $ids = array_pluck($messages['data'], 'id');
            ChatMessage::whereIn('id', $ids)
                ->update([
                    'is_read' => 1
                ]);
        }

        foreach ($messages['data'] as $k => $message) {
            if (data_get($message, 'user_id', '') == $user->id) {
                $messages['data'][$k]['who'] = 1;
                $messages['data'][$k]['nickname'] = data_get($cuser, 'name');
                $messages['data'][$k]['head_img'] = data_get($cuser, 'head_img');

            } else {
                $messages['data'][$k]['who'] = 2;
                $messages['data'][$k]['nickname'] = data_get($toUser, 'name');
                $messages['data'][$k]['head_img'] = data_get($toUser, 'head_img');
            }
        }
        $messages['data'] = array_reverse($messages['data']);


        return $this->formatOutput($messages);
    }

    public function contactUs(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $mobile = data_get($params, 'mobile', '');
        $text = data_get($params, 'text', '');
        $type = data_get($params, 'type', '');
        $reportUserId = data_get($params, 'report_user_id', 0);

        if (empty($type)) {
            throw new \LogicException('缺少必要参数', 100);
        }

        if (empty($text)) {
            throw new \LogicException('请输入内容', 100);
        }
        $appId = config('payment.jueqiweilaixcx.wechat.app_id');
        $secret = '';
        if ($appId == config('payment.jueqiweilaixcx.wechat.app_id')) {
            $secret = config('payment.jueqiweilaixcx.wechat.app_secret');
        }
        $wechat  = new WechatService($appId, $secret);
        $r = $wechat->msgSecCheck($text);
        ContactUs::create([
            'user_id' => $user->id,
            'text' => $text,
            'mobile' => $mobile,
            'report_user_id' => $reportUserId,
            'type' => $type,
        ]);

        return $this->formatOutput('success');
    }


    public function contactUsIndex(Request $request)
    {

    }

    public function addWxMsgCount(Request $request)
    {
        $params = $request->all();
        $user = authUser();
        $count = data_get($params, 'count', 1);
        $appId = data_get($params, 'app_id', config("payment.jueqiweilaixcx.wechat.app_id", ''));
        $uoi = \DB::table('users_open_ids')
            ->where('app_id', '=', $appId)
            ->where('user_id', '=', $user->id)
            ->first();

        $uoi->increment('notify_count', $count);

        return $this->formatOutput('success');

    }

    /**
     * 我邀请了谁
     * @param Request $request
     * @return array
     */
    public function IinvitedWho(Request $request)
    {
        $user = authUser();
        $params = $request->all();
        $pageSize = data_get($params, 'page_size', 20);
        $page = data_get($params, 'page', 1);
        $r = User::where('share_user_id', '=', $user->id)
            ->orderBy('be_shared_at', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page)
            ->toArray();

        return $this->formatOutput($r);
    }

    /**
     * 谁邀请了我
     * @param Request $request
     * @return array
     */
    public function whoInvitedMe(Request $request)
    {
        $user = authUser();
        $params = $request->all();
        $r = User::where('id', '=', $user->share_user_id)
            ->first();

        return $this->formatOutput($r);
    }
}
